//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include "cparser.h"

#include "ctokenizer.h"
#include <buola/zz/repeat.h>
#include <buola/zz/operators.h>
#include <buola/scene/transform/crttransform.h>

#include "znode.h"

namespace buola { namespace scene { namespace vrml {

CParser::CParser()
{
    CreateGrammar();
}

void CParser::CreateGrammar()
{
    //A.2 General
    auto rURLList=ztoken(TOKEN_STRING)|(ztoken(TOKEN_LEFT_SQUARE)>>*ztoken(TOKEN_STRING)>>ztoken(TOKEN_RIGHT_SQUARE));
    auto rExternInterfaceDecl=(ztokentype(TOKENTYPE_KW_EVENTORFIELD)>>ztokentype(TOKENTYPE_FIELDTYPE)>>ztoken(TOKEN_IDENTIFIER));

    rExternProto=ztoken(TOKEN_KW_EXTERNPROTO) >> ztoken(TOKEN_IDENTIFIER) >>
                 ztoken(TOKEN_LEFT_SQUARE) >> *rExternInterfaceDecl >> ztoken(TOKEN_RIGHT_SQUARE) >>
                 rURLList;
    rRouteStatement=ztoken(TOKEN_KW_ROUTE) >> 
                    ztoken(TOKEN_IDENTIFIER) >> ztoken(TOKEN_PERIOD) >> ztoken(TOKEN_IDENTIFIER) >> 
                    ztoken(TOKEN_KW_TO) >> 
                    ztoken(TOKEN_IDENTIFIER) >> ztoken(TOKEN_PERIOD) >> ztoken(TOKEN_IDENTIFIER);
}

PTransform CParser::Parse(const std::vector<char> &pFile)
{
    auto lI=pFile.begin();
    std::vector<CToken> lTokens;

    msg_info() << "tokenizing\n";
    start_timer();
    if(!mTokenizer.Tokenize(lI,pFile.end(),lTokens))
        throw XInvalid("error tokenizing VRML file");
    end_timer();
    
    TTokenIt lTI=lTokens.begin(),lTE=lTokens.end();

    mParserStatus=STATUS_OK;
    bool lResult;
    msg_info() << "parsing\n";
    start_timer();
    std::vector<PProto> lProtos;
    std::vector<PNode> lNodes;
    
    auto rVRMLScene=*(znode(this)--[lNodes]|zproto(this)--[lProtos]|rExternProto|rRouteStatement)>>ztoken(TOKEN_EOI);

    lResult=zz::parse(lTI,lTE,rVRMLScene);
    end_timer();

    if(!lResult||lTI!=lTE)
    {
        msg_info() << "parse failed!!!!\n";
        throw XInvalid("couldn't parse VRML file");
    }

    return lProtos[0]->ExtractRobot();
}

    
/*namespace vrml*/ } /*namespace scene*/ } /*namespace buola*/ }
